#ifndef SESSION_H
#define SESSION_H

#include <iostream>
#include <boost\asio.hpp>
#include "message.h"
#include "drive.pb.h"

namespace comunication {

	typedef boost::asio::ip::tcp tcp;
	typedef boost::asio::io_service io_service;

	class session
	{
	public:
		session(io_service& io_service):
			socket_(io_service), is_connected(false)
		{
		}

		void start()
		{
			std::cout<<"Session connected" <<std::endl;
			boost::asio::async_read(socket_,
				boost::asio::buffer(read_msg_.get_header_data(), message::header_length),
				boost::bind(&session::handle_read_body, this, boost::asio::placeholders::error));
			is_connected = true;
		}

		bool is_client_connected()
		{
			return is_connected;
		}

		tcp::socket& socket()
		{
			return socket_;
		}

	private:
		void handle_read_header(const boost::system::error_code& error)
		{
			if (!error) {
				drive dr;
				if (dr.ParseFromArray(read_msg_.get_body_data(), read_msg_.get_size()))
				{
					std::cout<<"Direction: "<<dr.direction()<<" angle :"<<dr.wheel_angle()<<std::endl;
				
				} else {
					std::cout<<"DUPA"<<std::endl;
				}
				read_msg_.clear();

				boost::asio::async_read(socket_,
					boost::asio::buffer(read_msg_.get_header_data(), message::header_length),
					boost::bind(&session::handle_read_body, this, boost::asio::placeholders::error));
			} else {
				is_connected = false;
			}
		}

		void handle_read_body(const boost::system::error_code& error)
		{
			if ((!error) && (read_msg_.decode_header()))
			{
				std::cout<<"Recived msg id "<<read_msg_.get_id()<<" size: "<<read_msg_.get_size()<<std::endl;
				boost::asio::async_read(socket_,
					boost::asio::buffer(read_msg_.get_body_data(), read_msg_.get_size()),
					boost::bind(&session::handle_read_header, this, boost::asio::placeholders::error));
			} else {
				is_connected = false;
			}
		}

		tcp::socket socket_;
		bool is_connected;
		message read_msg_;
	};
}
#endif